import pymysql
from config import config
from datetime import datetime
import hashlib

class UserModel:
    """用户模型类 - 数据访问层"""
    
    def __init__(self):
        # 不在初始化时创建连接，而是在每次需要时创建
        self.connection = None
    
    def get_connection(self):
        """获取数据库连接"""
        # 每次都创建新的连接，避免连接缓存问题
        connection = pymysql.connect(
            host=config.MYSQL_HOST,
            port=config.MYSQL_PORT,
            user=config.MYSQL_USER,
            password=config.MYSQL_PASSWORD,
            database=config.MYSQL_DATABASE,
            charset='utf8mb4',
            cursorclass=pymysql.cursors.DictCursor
        )
        return connection
    
    def close_connection(self, connection):
        """关闭数据库连接"""
        if connection and connection.open:
            connection.close()
    
    def encrypt_password(self, password):
        """密码加密 - 使用更安全的SHA256加盐加密"""
        # 生成随机盐值
        import secrets
        salt = secrets.token_hex(16)
        # 使用SHA256加密密码和盐值
        password_hash = hashlib.sha256((password + salt).encode()).hexdigest()
        return f"{salt}${password_hash}"
    
    def verify_password(self, password, hashed_password):
        """验证密码"""
        if not hashed_password or '$' not in hashed_password:
            return False
        salt, stored_hash = hashed_password.split('$', 1)
        password_hash = hashlib.sha256((password + salt).encode()).hexdigest()
        return password_hash == stored_hash
    
    def get_user_by_username(self, username):
        """根据用户名获取用户信息"""
        connection = None
        try:
            connection = self.get_connection()
            with connection.cursor() as cursor:
                sql = "SELECT * FROM user WHERE username = %s"
                cursor.execute(sql, (username,))
                result = cursor.fetchone()
                return result
        except Exception as e:
            print(f"查询用户失败: {e}")
            return None
        finally:
            self.close_connection(connection)
    
    def verify_user_credentials(self, username, password):
        """验证用户凭据（加密密码比较）"""
        user = self.get_user_by_username(username)
        if not user:
            return None
        
        # 使用加密密码比较
        if self.verify_password(password, user['password']):
            # 返回用户信息（不包含密码）
            return {
                'id': user['id'],
                'username': user['username'],
                'nickname': user['nickname'],
                'phone': user['phone'],
                'email': user['email'],
                'driving_years': user['driving_years'],
                'city': user['city'],
                'birthday': user['birthday'],
                'bio': user['bio'],
                'created_at': user['created_at']
            }
        return None
    
    def create_user(self, user_data):
        """创建新用户（加密密码存储）"""
        connection = None
        try:
            connection = self.get_connection()
            with connection.cursor() as cursor:
                # 检查用户名是否已存在
                check_sql = "SELECT id FROM user WHERE username = %s"
                cursor.execute(check_sql, (user_data['username'],))
                existing_user = cursor.fetchone()
                
                if existing_user:
                    return {'success': False, 'message': '用户名已存在'}
                
                # 加密密码
                if 'password' in user_data:
                    user_data['password'] = self.encrypt_password(user_data['password'])
                
                # 设置默认值，确保可选字段为NULL而不是空字符串
                user_data.setdefault('nickname', user_data.get('nickname', ''))
                # 将空字符串转换为None，以避免唯一约束冲突
                user_data['phone'] = user_data.get('phone') or None
                if user_data['phone'] == '':
                    user_data['phone'] = None
                    
                user_data['email'] = user_data.get('email') or None
                if user_data['email'] == '':
                    user_data['email'] = None
                    
                user_data.setdefault('driving_years', 0)
                user_data['city'] = user_data.get('city') or None
                if user_data['city'] == '':
                    user_data['city'] = None
                    
                user_data['birthday'] = user_data.get('birthday') or None
                user_data['bio'] = user_data.get('bio') or None
                if user_data['bio'] == '':
                    user_data['bio'] = None
                    
                user_data.setdefault('created_at', datetime.now())
                
                # 插入用户数据
                sql = """
                INSERT INTO user (username, password, nickname, phone, email, driving_years, city, birthday, bio, created_at)
                VALUES (%(username)s, %(password)s, %(nickname)s, %(phone)s, %(email)s, %(driving_years)s, %(city)s, %(birthday)s, %(bio)s, %(created_at)s)
                """
                cursor.execute(sql, user_data)
                connection.commit()
                
                return {
                    'success': True, 
                    'message': '用户创建成功',
                    'user_id': cursor.lastrowid
                }
        except Exception as e:
            print(f"创建用户失败: {e}")
            if connection:
                connection.rollback()
            return {'success': False, 'message': '创建用户失败'}
        finally:
            self.close_connection(connection)
    
    def register_user(self, username, password, nickname=None):
        """用户注册方法"""
        # 生成默认昵称
        if not nickname:
            import secrets
            import string
            # 生成10位随机字符串 + '_user'
            random_str = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(10))
            nickname = f"{random_str}_user"
        
        user_data = {
            'username': username,
            'password': password,
            'nickname': nickname
        }
        
        return self.create_user(user_data)
    
    def update_user(self, username, user_data):
        """更新用户信息"""
        connection = None
        try:
            connection = self.get_connection()
            with connection.cursor() as cursor:
                # 构建更新语句
                update_fields = []
                params = []
                
                # 只更新提供的字段
                allowed_fields = ['nickname', 'phone', 'email', 'driving_years', 'city', 'birthday', 'bio', 'avatar']
                for field in allowed_fields:
                    if field in user_data:
                        update_fields.append(f"{field} = %s")
                        # 处理空字符串，将其转换为None
                        value = user_data[field] if user_data[field] != '' else None
                        params.append(value)
                
                if not update_fields:
                    return {'success': False, 'message': '没有要更新的字段'}
                
                # 添加用户名作为WHERE条件
                params.append(username)
                
                sql = f"UPDATE user SET {', '.join(update_fields)} WHERE username = %s"
                cursor.execute(sql, params)
                connection.commit()
                
                return {
                    'success': True, 
                    'message': '用户信息更新成功'
                }
        except Exception as e:
            print(f"更新用户信息失败: {e}")
            if connection:
                connection.rollback()
            return {'success': False, 'message': '更新用户信息失败'}
        finally:
            self.close_connection(connection)
    
    def is_phone_exists(self, phone, exclude_username=None):
        """检查电话号码是否存在（排除指定用户名）"""
        connection = None
        try:
            connection = self.get_connection()
            with connection.cursor() as cursor:
                if exclude_username:
                    sql = "SELECT id FROM user WHERE phone = %s AND username != %s"
                    cursor.execute(sql, (phone, exclude_username))
                else:
                    sql = "SELECT id FROM user WHERE phone = %s"
                    cursor.execute(sql, (phone,))
                result = cursor.fetchone()
                return result is not None
        except Exception as e:
            print(f"检查电话号码失败: {e}")
            return False
        finally:
            self.close_connection(connection)
    
    def is_email_exists(self, email, exclude_username=None):
        """检查邮箱是否存在（排除指定用户名）"""
        connection = None
        try:
            connection = self.get_connection()
            with connection.cursor() as cursor:
                if exclude_username:
                    sql = "SELECT id FROM user WHERE email = %s AND username != %s"
                    cursor.execute(sql, (email, exclude_username))
                else:
                    sql = "SELECT id FROM user WHERE email = %s"
                    cursor.execute(sql, (email,))
                result = cursor.fetchone()
                return result is not None
        except Exception as e:
            print(f"检查邮箱失败: {e}")
            return False
        finally:
            self.close_connection(connection)